package org.geppeto.eva.eventory;

import java.io.*;
import java.util.UUID;

import javax.servlet.http.HttpServletRequest;
import javax.xml.parsers.*;
import javax.xml.transform.*;
import javax.xml.transform.dom.*;
import javax.xml.transform.stream.*;
import org.w3c.dom.*;
import org.xml.sax.*;

//Treba mi JSON jer cu tako spremati presonalized
// http://lemnik.wordpress.com/2009/01/29/an-automated-json-encoder-and-decoder-for-java/

/**
 * @author Miroslav Popovic
 *
 */

public class Repository {
	
	public static String SPEC_TICKET_OFFICE_FILE_NAME = "ticket_office.xml";
	public static String SPEC_MEET_UP_FILE_NAME = "meet_up.xml";
	public static String SPEC_TRASACTION_FILE_NAME = "transaction.xml";
	public static String DIR_PATH_TEMPLATES = "/src/main/java/org/geppeto/eva/eventory";
	public static String DIR_PATH_PERSONALS = "/src/main/java/org/geppeto/eva/eventory/personals";
		
	private String currentDir;
	private String dirTemplates;
	private String dirPersonals;
	
	public Repository (){
		this.currentDir = System.getProperty("user.dir");
		this.dirTemplates = currentDir + DIR_PATH_TEMPLATES;
		this.dirPersonals = currentDir + DIR_PATH_PERSONALS;
	};
	

	public String getSpec(String personalKey) {
		try {
			String data = readFile(dirPersonals + "/" + personalKey);
			//TODO fill this data to the Specification
			return data;			
		} catch (IOException e) {
			return "Fault";
		}
	}
	
	public String getBlankSpec(String typeOfMechanism){
		try {			
			return readFile(dirTemplates + typeOfMechanism);
		} catch (IOException e) {
			return "Fault";
		}
	}
	
	private String createFileIfItDoesntExist(String directoryPath, String fileName, String xmlRoot ){
		try {
			// Check if user directory exists
			File directory = new File(directoryPath);
			if (!directory.exists()) {
				directory.mkdirs();
			}
			File file = new File(directoryPath + "/" + fileName);
			if (!file.exists()){
				file.createNewFile();
				if (xmlRoot != null ){
					DocumentBuilderFactory documentBuilderFactory = 
						DocumentBuilderFactory.newInstance();

					DocumentBuilder documentBuilder = 
						documentBuilderFactory.newDocumentBuilder();

					Document doc = documentBuilder.newDocument();

					Element rootElement = doc.createElement(xmlRoot);
					doc.appendChild(rootElement);

					Source source = new DOMSource(doc);

					//Prepare the output file            
					Result result = new StreamResult(file);

					// Write the DOM document to the file
					Transformer xformer = TransformerFactory.newInstance().newTransformer();
					xformer.transform(source, result);	
				}	        
			}
			return "true";
		} catch (Exception err) {
			return "failed";
		}
	}

	private Document loadXmlFromFile(String fullFilePath){
		try{
			File file = new File(fullFilePath);	
			DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
			DocumentBuilder db = dbf.newDocumentBuilder();
			Document doc = db.parse(file);
			doc.getDocumentElement().normalize();
			return doc;
		} catch (Exception err) {
			return null;
		}
	}

	private String saveXmlToFile(String fullFilePath, Document doc) {
		try {
			File file = new File(fullFilePath);
			TransformerFactory transformerFactory = TransformerFactory.newInstance();
			Transformer transformer = transformerFactory.newTransformer();
			DOMSource source = new DOMSource(doc);		      
			StreamResult result = new StreamResult(file);		    
			transformer.transform(source, result);
			return "success";
		} catch (Exception err) {
			return err.getMessage();
		}
	} 

	private String readFile(String filePath) throws IOException {

		File file = new File(filePath);
		String xmlSpec = "";
		if (file.exists()) {
			FileInputStream fis = new FileInputStream(file);
			DataInputStream in = new DataInputStream(fis);
			BufferedReader br = new BufferedReader(new InputStreamReader(in));
			String add = "";
			while ((add = br.readLine()) != null) {
				xmlSpec += add;
			}
			br.close();
			in.close();
			fis.close();
		}
		return xmlSpec;	
	}

	private String saveXmlSpecGadget(String dirPath, String filePath, String xmlSpec) 
	throws ParserConfigurationException, SAXException, IOException, TransformerException {

		xmlSpec = removeNonPrintableChars(xmlSpec);

		// Create a factory object for creating DOM parsers
		DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
		// Now use the factory to create a DOM parser (a.k.a. a DocumentBuilder)
		DocumentBuilder parser = factory.newDocumentBuilder();
		//Parse the document
		Reader reader=new CharArrayReader(xmlSpec.toCharArray());
		Document doc = parser.parse(new org.xml.sax.InputSource(reader));
		//Create empty xml document if it does not exist
		createFileIfItDoesntExist(dirPath, filePath, null);
		saveXmlToFile(filePath, doc);
		return "";
	}


	/**
	 * Gets rid of the non printable chars in the string   
	 * @param directoryPath is full path to directory
	 * @return null if not success, string that was truncated if success
	 */		
	private String removeNonPrintableChars(String originalString) {
		try {
			String truncated = originalString.replaceAll("\\p{Cntrl}", "");
			return truncated;
		} catch (Exception err) {
			return null;
		}
	} 

	private String deleteFile(String fullFilePath) {
		try {
			File f = new File(fullFilePath);

			// Make sure the file or directory exists and isn't write protected
			if (!f.exists())
				return "failed: no such file or directory: " + fullFilePath;

			if (!f.canWrite())
				return "failed: write protected: " + fullFilePath;

			// If it is a directory, make sure it is empty
			if (f.isDirectory()) {
				String[] files = f.list();
				if (files.length > 0)
					return "failed: directory not empty: " + fullFilePath;
			}

			// Attempt to delete it
			boolean success = f.delete();

			if (!success)
				return "failed: deletion failed";
			else return "success";
		} catch (Exception err) {
			return err.getMessage();
		}
	}

	private Boolean isValidUrl(String url) {
		String [] a = url.split(" ");
		if (a.length > 1) return false;
		return true;
	}






}
